Skip to content

Finish MRI's message-quoting migration: 13 sites still wrote `x' where 4.0 writes 'x' - #900

Merged
tannevaled merged 2 commits into
mainfrom
straight-quotes-in-messages
Nov 5, 2026
Merged

tannevaled merged 2 commits into
mainfrom
straight-quotes-in-messages

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

MRI stopped writing `name' and writes 'name' since 3.4. v4.0.9 is straight-quoted throughout — numeric.c:3207 and file.c:3908, both read from the tag.

rbgo migrated most of its messages and missed thirteen sites. That was only visible because the same message ended up in both spellings in one package:

builtins.go:3321   raise("RangeError", "bignum too big to convert into 'long'")
arith.go:675       raise("RangeError", "bignum too big to convert into `long'")

That is not a style choice. It is half a migration.

What was missed

site message
arith.go:675, builtins.go:6028, numeric_edges.go:53 bignum too big to convert into `long'
numeric_edges.go:49 integer %d too big to convert to `int'
builtins.go:10288, modulefunc.go:534 `%s' is not allowed as a class variable name
ivar_reflect.go:71 `%s' is not allowed as an instance variable name
dir.go:503, file.go:1010 couldn't find HOME environment -- expanding `~'
oauth2_client.go:91, opentelemetry.go:116, rspec.go:252, rspec.go:260 undefined method `x' for …

The last four imitate NoMethodError, which rbgo's own dispatcher already writes with straight quotes — they disagreed with the engine they sit in.

The search was widened because the probe was narrow

A probe of twelve NameError shapes against MRI 4.0.7 named five. Fixing those five would have left eight behind, so the search widened to every raise( in the package carrying a backtick: 47 lines, of which 13 were this family.

The two tests moved with the quoting, not because they were wrong

module_wave16_internal_test.go pinned `foo' and `@@'. Both now pin the 4.0 form, with the two citations beside them, so a reader who finds this diff later knows the expectation changed because MRI's did.

The gate

A note saying "finish the migration" would be forgotten exactly the way the first half was, so message_quoting_test.go scans every non-test source file in the package and fails on the old form. It logs how many files it read (542) and refuses below 50 — a scan that cannot say what it looked at cannot be told from a scan that could not look.

⛔ The gate's own first version was wrong, and its test now says so

Matching the whole line reported string_undump.go twice. That message is a Go raw string, where the backtick is the delimiter and not part of the message at all. A detector that cannot tell a delimiter from content reports defects that are not there — so the detector is now a function with six rows of its own, covering that raw string, prose that pairs its backticks, and an escaped quote inside a message.

Measured

rubydiff against /opt/homebrew/opt/ruby@4.0/bin/ruby on twelve NameError/RangeError shapes: DIVERGE on 5 before, AGREE after. go vet ./... clean.

Two unrelated divergences the probe turned up

Filed separately rather than fixed here, since neither is about quoting:

  • Array.new(2**128) → MRI RangeError: bignum too big to convert into 'long', rbgo ArgumentError: array size too big — a different class, not just a different message.
  • File.expand_path("~") with HOME deleted → MRI does not raise at all; rbgo raises ArgumentError.

🤖 Generated with Claude Code

MRI stopped writing `name' and writes 'name' since 3.4. v4.0.9 is straight-quoted
throughout -- numeric.c:3207 "integer %lu too big to convert to 'unsigned int'",
file.c:3908 "couldn't find HOME environment -- expanding '~'", both read from the
tag.

rbgo migrated most of its messages and missed thirteen sites. It was only
visible because the SAME message ended up in both spellings in one package:

    builtins.go:3321   "bignum too big to convert into 'long'"
    arith.go:675       "bignum too big to convert into `long'"

That is not a style choice, it is half a migration.

## What was missed

    arith.go:675            bignum too big to convert into `long'
    builtins.go:6028        bignum too big to convert into `long'
    builtins.go:10288       `%s' is not allowed as a class variable name
    dir.go:503              couldn't find HOME environment -- expanding `~'
    file.go:1010            couldn't find HOME environment -- expanding `~'
    ivar_reflect.go:71      `%s' is not allowed as an instance variable name
    modulefunc.go:534       `%s' is not allowed as a class variable name
    numeric_edges.go:49     integer %d too big to convert to `int'
    numeric_edges.go:53     bignum too big to convert into `long'
    oauth2_client.go:91     undefined method `authorize_url' for %s
    opentelemetry.go:116    undefined method `add_span_processor' for ...
    rspec.go:252            undefined method `of' for matcher
    rspec.go:260            undefined method `with' for matcher

The last four imitate NoMethodError, which rbgo's own dispatcher already writes
with straight quotes -- they disagreed with the engine they sit in.

## How it was found, and how the search was widened

A probe of twelve NameError shapes against MRI 4.0.7 named FIVE. Fixing those
five would have left eight, so the search was widened to every raise() in the
package carrying a backtick: 47 lines, of which 13 were this family.

## The two tests moved with the quoting, not because they were wrong

module_wave16_internal_test.go pinned `foo' and `@@'. Both now pin the 4.0 form
with the two citations above beside them, so a reader finding this diff later
knows the expectation changed because MRI's did.

## The gate

A note saying "finish the migration" would be forgotten exactly the way the
first half was, so message_quoting_test.go scans every non-test source file in
the package and fails on the old form. It logs how many files it read (542) and
refuses below 50: a scan that cannot say what it looked at cannot be told from a
scan that could not look.

## The gate's own first version was wrong, and its test says so

Matching the whole line reported string_undump.go twice. That message is a Go
RAW string, where the backtick is the DELIMITER and not part of the message. A
detector that cannot tell a delimiter from content reports defects that are not
there, so the detector is now a function with six rows of its own -- including
that raw string, prose that pairs its backticks, and an escaped quote inside a
message.

## Measured

rubydiff against /opt/homebrew/opt/ruby@4.0/bin/ruby on twelve NameError and
RangeError shapes: DIVERGE on 5 before, AGREE after.

go vet ./... clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@tannevaled
tannevaled merged commit c6d68a6 into main Nov 5, 2026
26 checks passed
@tannevaled
tannevaled deleted the straight-quotes-in-messages branch November 5, 2026 20:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant